package array_tree

import "errors"

type MTree struct {
	MData []interface{}
	MSize int64
}

func NewMTree(m_size int64, rootNodeData interface{}) (*MTree, error) {
	if (m_size < 1) {
		return nil, errors.New("error size")
	}
	m_data := []interface{}{}
	var i int64 = 0;
	for ; i < m_size; i++ {
		m_data = append(m_data, nil)
	}
	m_data[0] = rootNodeData
	return &MTree{
		MData: m_data,
		MSize: m_size,
	}, nil
}

func (m *MTree) AddNode(nodeIndex int64, direction int, nodeValue interface{}) error {
	if nodeIndex > m.MSize-1 || nodeIndex < 0 {
		return errors.New("index error")
	}
	if m.MData[nodeIndex] == nil{
		return errors.New("parent is nil")
	}
	if nodeValue == nil {
		return errors.New("nodeValue not exists")
	}
	var childIndex int64
	if direction == 0 {
		childIndex = nodeIndex*2 + 1
	} else {
		childIndex = nodeIndex*2 + 2
	}
	if childIndex > m.MSize-1 {
		return errors.New("child index error")
	}
	m.MData[childIndex] = nodeValue
	return nil
}

func (m *MTree) SearchNode(nodeIndex int64) (interface{}, error) {
	if nodeIndex > m.MSize-1 || nodeIndex < 0 {
		return nil, errors.New("index error")
	}
	if m.MData[nodeIndex] == nil {
		return nil, errors.New("nodeIndex not exists")
	}
	return m.MData[nodeIndex], nil
}

func (m *MTree) DeleteNode(nodeIndex int64) (interface{},error) {
	if nodeIndex > m.MSize-1 || nodeIndex < 0 {
		return nil,errors.New("index error")
	}
	if m.MData[nodeIndex] == nil {
		return nil,errors.New("nodeIndex not exists")
	}
	if (nodeIndex*2+1 <= m.MSize-1) {
		_,_ = m.DeleteNode(nodeIndex*2 + 1)
	}
	if (nodeIndex*2+2 <= m.MSize-1) {
		_,_ = m.DeleteNode(nodeIndex*2 + 2)
	}
	nodeVaue := m.MData[nodeIndex]
	m.MData[nodeIndex] = nil
	return nodeVaue,nil
}

func (m *MTree) TraverseTree() {
	var i int64 = 0;
	for ; i < m.MSize; i++ {
		if m.MData[i] != nil {
			println(i, m.MData[i].(int))
		} else {
			println(i, "nil")
		}
	}
}
